package com.hmall.item;

import com.alibaba.fastjson.JSON;
import com.hmall.item.domain.dto.ItemESDTO;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;

//@SpringBootTest
public class ES02Test {

    private RestHighLevelClient client;

    @BeforeEach
    void setUp() {
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.101.200:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        client.close();
    }


    /**
     *  1 搜索 所有商品
     * @throws IOException
     */
    @Test
    void testSearchDemo() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(QueryBuilders.matchAllQuery());
        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
        dataPase(response);
    }

    private void dataPase(SearchResponse response) {
        long total = response.getHits().getTotalHits().value;
        System.out.println("总条数：" + total);
        //提取当前页数据
        SearchHit[] hits = response.getHits().getHits();
        for (int i=0; i<hits.length; i++){
            System.out.println(hits[i].getSourceAsString());
        }
    }

    /**
     * 2. 搜索  名字：脱脂牛奶
     *
     */
    @Test
    void testSearch2() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(QueryBuilders.matchQuery("name","脱脂牛奶"));
        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
        dataPase(response);

    }

    /**
     * 3. 搜索  品牌：德亚
     *
     */
    @Test
    void testSearch3() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(QueryBuilders.termQuery("brand","德亚"));
        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
        dataPase(response);
    }


    /**
     * 4. 搜索   价格：10000 -30000
     *
     */
    @Test
    void testSearch4() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(10000).lte(30000));
        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
        dataPase(response);
    }

    /**
     * 5. Bool搜索  名字：脱脂牛奶  品牌：德亚  价格： < 30000
     *
     */
    @Test
    void testBoolSearch5() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(

        );
        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
        dataPase(response);
    }



    /**
     * 6. 搜索所有商品，价格倒序排列，查询第一页5条
     *
     */

    @Test
    void testSortAndPage() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(QueryBuilders.matchAllQuery());
        searchRequest.source().sort("price", SortOrder.DESC);
        searchRequest.source().from(0).size(5);
        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
        dataPase(response);
    }


    /**
     * 7. "name", "脱脂牛奶"， 并对关键字 高亮显示
     *
     */
    @Test
    void testHighlight() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(QueryBuilders.matchQuery("name","脱脂牛奶"));
        searchRequest.source().highlighter(
                SearchSourceBuilder.highlight()
                        .field("name")
                        .requireFieldMatch(false)
                );

        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
        long total = response.getHits().getTotalHits().value;
        System.out.println("总条数：" + total);
        //提取当前页数据
        SearchHit[] hits = response.getHits().getHits();
        for (int i=0; i<hits.length; i++){
            //将元素的json数据转为dto对象接收
            ItemESDTO itemDto = JSON.parseObject(hits[i].getSourceAsString(), ItemESDTO.class);
            System.out.println(itemDto);
            //获取高亮字段
            hits[i].getHighlightFields().forEach(
                    (fieldName, highlightField)->{
                    //高亮后替换
                System.out.println(highlightField.getFragments()[0].toString());
            });
        }

    }
    @Test
    void testBucket() throws IOException {
        //1.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("items");
        //2.组装查询条件
        searchRequest.source().query(QueryBuilders.termQuery("category","手机"));
        searchRequest.source().aggregation(
                AggregationBuilders.terms("brand_agg").field("brand").size(10)
        );

        //3．发送请求，执行搜索
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4．解析响应数据
        //取出总条数
       ParsedStringTerms brandAgg = response.getAggregations().get("brand_agg");
       brandAgg.getBuckets().forEach(
               bucket->{
                   System.out.println("品牌名"+bucket.getKeyAsString()+"数量"+bucket.getDocCount());
               }
       );
    }

}